package dms.repository.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;



import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import dms.model.Building;
import dms.model.Campus;
import dms.model.Dormitory;
import dms.model.form.LowElectricity;
import dms.model.form.Mail;
import dms.model.util.FindUtil;
import dms.model.util.PageIterator;
import dms.repository.LowElectricityRepository;
import dms.util.HibernateUtil;

public class LowElectricityRepositoryHibernate implements LowElectricityRepository {
	private static final Log log = LogFactory.getLog(MailRepositoryHibernate.class);
	
	public LowElectricity findById(Long id)
	{
		Session session = null;
		Transaction tx = null;
		
		LowElectricity lowElecInfo  = null;
		
		try {
			session = HibernateUtil.getSessionFactory().getCurrentSession();
			tx = session.beginTransaction();
			
			lowElecInfo = (LowElectricity) session.load(LowElectricity.class, id);			
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();	
		}		
		return lowElecInfo;	
	}
	public LowElectricity createLowElectricity(
			LowElectricity lowElecInfo) throws Exception {
		Session session=null;
		Transaction tx = null;
		try {
			session = HibernateUtil.getSessionFactory().getCurrentSession();
			tx = session.beginTransaction();

			session.save(lowElecInfo);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} 
		return lowElecInfo;
	}

	@Override
	public void deleteById(Long id) throws Exception {
		Session session = null;
		Transaction tx = null;
		try {
			String deleteHql = "delete from LowElectricity as m where m.id=?";
			session = HibernateUtil.getSessionFactory().getCurrentSession();
			tx = session.beginTransaction();
			Query query = session.createQuery(deleteHql);
			query.setLong(0, id);
			query.executeUpdate();
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
			throw e;
		}
	}
	
	@Override
	public void delete(List<Long> ids) throws Exception {
		Session session = null;
		Transaction tx = null;
		String deleteQuery = "delete from LowElectricity l where l.id in (:ids)";
		try {
			session = HibernateUtil.getSessionFactory().getCurrentSession();
			tx = session.beginTransaction();
			
			Query query = session.createQuery(deleteQuery);
			query.setParameterList("ids", ids);
			query.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			throw e;
		}
	}
	
	@Override
	public PageIterator<LowElectricity> findByBuilding(int start,
			int count, Building building, Date fromDate, Date toDate) {
		Map keyValue = new HashMap();
		keyValue.put("dormitory.building", building);
		return find(start, count, keyValue, fromDate, toDate);
	}

	private PageIterator<LowElectricity> find(int start, int count,
			Map keyValue, Date fromDate, Date toDate) {
	
		Session session = null;
		Transaction tx = null;
		List<LowElectricity> list = null;
		PageIterator<LowElectricity> iter = null;
		Long allCount = null;		
		
		String countQuery = "select count(*) from LowElectricity m  ";
		String findQuery = "select m from LowElectricity m  ";
		StringBuilder conditionQuery = new StringBuilder();
		
		if (!keyValue.isEmpty()) {
			conditionQuery.append(" where ") ;
		}
		
		Set set = keyValue.entrySet();
		Iterator<LowElectricityRepository> keyIter = set.iterator();
		
		Collection params = new ArrayList();
				
		while (keyIter.hasNext()) {
			Map.Entry<String, Object> entry = (Entry<String, Object>) keyIter.next();
			String name = entry.getKey();
			Object value = entry.getValue();
			
			conditionQuery.append(" m." + name + " = ? and ") ;
			params.add(value);
		}
		
		if (conditionQuery.indexOf("where") == -1) {
			conditionQuery.append(" where ");
		}
		if (fromDate != null && toDate == null) {
			conditionQuery.append("  m.date >= ?  and ");
			params.add(fromDate);
		}
		if (fromDate == null && toDate != null) {
			conditionQuery.append("  m.date <= ?  and ");
			params.add(toDate);
		}
		if (fromDate != null && toDate != null) {
			conditionQuery.append("  (m.date between ? and ?)  and ");
			params.add(fromDate);
			params.add(toDate);
		}

		
		conditionQuery.append(" m.id = m.id ");
		countQuery += conditionQuery.toString();
		findQuery += conditionQuery.toString();
		
		try {
			session = HibernateUtil.getSessionFactory().getCurrentSession();
			tx = session.beginTransaction();
			
			allCount = FindUtil.calculateAllCount(session, countQuery, params);
			list = FindUtil.getEntitiesByPage(session, findQuery, params, start, count);
			iter = new PageIterator<LowElectricity>(list, allCount, start, count);			
		} catch (Exception e) {
			log.error(e.toString());
			e.printStackTrace();
		}
		return iter;
	}

	@Override
	public PageIterator<LowElectricity> findByDormitory(int start,
			int count, Dormitory dormitory, Date fromDate, Date toDate) {
		Map keyValue = new HashMap();
		keyValue.put("dormitory", dormitory);
		
		return this.find(start, count, keyValue, fromDate, toDate);
	}

	@Override
	public LowElectricity updateLowElectricity(LowElectricity lowelecInfo)
			throws Exception {

		Session session = null;
		Transaction tx = null;

		LowElectricity lowInfo = null;

		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			lowInfo = (LowElectricity) session.merge(lowelecInfo);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
			throw e;
		}
		return lowInfo;
	}
	@Override
	public PageIterator<LowElectricity> findByCampus(int start, int count,
			Campus campus, Date fromDate, Date toDate) {
		Map keyValue = new HashMap();
		keyValue.put("dormitory.building.campus", campus);
		return this.find(start, count, keyValue, fromDate, toDate);
	}
}
